#include "ScrollableControl.hpp"
#include "Application.hpp"
#include <map>
#include "Page.hpp"
using namespace NAMESPACENAME;
extern std::map<HWND, Control*> __mapWindows;
ScrollableControl::ScrollableControl(const NAMESPACENAME::Rectangle& rect, ContainerControl* parent) :
	Control(parent),
	currectPage(0)
{
}
void ScrollableControl::OnSizing(SizingEventArgs& e)
{
	RECT rct;
	GetWindowRect(hWnd, &rct);
	NAMESPACENAME::Rectangle windowRect(rct);
	GetClientRect(hWnd, &rct);
	NAMESPACENAME::Rectangle clientRect(rct);
	GetClientRect(pages.at(currectPage)->WindowHandle(), &rct);
	NAMESPACENAME::Rectangle rect(rct);
	int borerOffsetX(windowRect.width - clientRect.width),
		borerOffertY(windowRect.height - clientRect.height);
	rect.height += borerOffertY;
	rect.width += borerOffsetX;
	e.rect->height = min(e.rect->height, rect.height);
	e.rect->width = min(e.rect->width, rect.width);
}
void ScrollableControl::OnSize(SizeEventArgs& e)
{
	if (!horizontalScrollBar || !verticalScrollBar)
	{
		verticalScrollBar = CreateWindowExW(
			0,
			L"ScrollBar",
			nullptr,
			WS_CHILD | SBS_VERT | SBS_RIGHTALIGN,
			0,
			0,
			e.newWidth,
			e.newHeight,
			hWnd,
			nullptr,
			Application::GetInstance(),
			nullptr
		);
		if (verticalScrollBar)
			__mapWindows.emplace(std::make_pair(verticalScrollBar, this));
		else
			throw std::exception("Create ScrollBar Failed!", 0);
		horizontalScrollBar = CreateWindowExW(
			0,
			L"ScrollBar",
			nullptr,
			WS_CHILD | SBS_HORZ | SBS_BOTTOMALIGN,
			0,
			0,
			e.newWidth - GetSystemMetrics(SM_CXHTHUMB),
			e.newHeight,
			hWnd,
			nullptr,
			Application::GetInstance(),
			nullptr
		);
		if (horizontalScrollBar)
			__mapWindows.emplace(std::make_pair(verticalScrollBar, this));
		else
			throw std::exception("Create ScrollBar Failed!", 0);
	}
	RECT rct;
	GetClientRect(pages.at(currectPage)->WindowHandle(), &rct);
	NAMESPACENAME::Rectangle pageRect(rct);
	SCROLLINFO sinfo;
	sinfo.cbSize = sizeof(sinfo);
	sinfo.fMask = SIF_PAGE | SIF_POS | SIF_RANGE;
	sinfo.nMin = 0;
	sinfo.nPos = sinfo.nTrackPos = 0;
	if (e.newHeight < pageRect.height)
	{
		sinfo.nMax = pageRect.height;
		sinfo.nPage = e.newHeight;
		SetScrollInfo(verticalScrollBar, SB_CTL, &sinfo, false);
		RECT br;
		GetWindowRect(verticalScrollBar, &br);
		MoveWindow(verticalScrollBar, e.newWidth - br.right + br.left, 0, br.right - br.left, e.newHeight, false);
		EnableScrollBar(verticalScrollBar, SB_CTL, ESB_ENABLE_BOTH);
		ShowScrollBar(verticalScrollBar, SB_CTL, true);
	}
	else
		ShowScrollBar(verticalScrollBar, SB_CTL, false);
	if (e.newWidth < pageRect.width)
	{
		sinfo.nMax = pageRect.width;
		sinfo.nPage = e.newWidth;
		SetScrollInfo(horizontalScrollBar, SB_CTL, &sinfo, false);
		RECT br;
		GetWindowRect(horizontalScrollBar, &br);
		MoveWindow(horizontalScrollBar, 0, e.newHeight - br.bottom + br.top, e.newWidth, br.bottom - br.top, false);
		EnableScrollBar(horizontalScrollBar, SB_CTL, ESB_ENABLE_BOTH);
		ShowScrollBar(horizontalScrollBar, SB_CTL, true);
	}
	else
		ShowScrollBar(horizontalScrollBar, SB_CTL, false);
	InvalidateRect(pages.at(currectPage)->WindowHandle(), nullptr, true);
	UpdateWindow(pages.at(currectPage)->WindowHandle());
}
void NAMESPACENAME::ScrollableControl::OnHorizontalScroll(ScrollEventArgs& e)
{
	RECT rct;
	GetClientRect(hWnd, &rct);
	NAMESPACENAME::Rectangle rect(rct);
	GetClientRect(pages.at(currectPage)->WindowHandle(), &rct);
	Rectangle pageRect(rct);
	switch (e.scrollType)
	{
	case ScrollEventArgs::ScrollType::Bottom:
		MoveWindow(pages.at(currectPage)->WindowHandle(), rect.width - pageRect.width, rect.height - pageRect.height, pageRect.width, pageRect.height, true);
		break;
	case ScrollEventArgs::ScrollType::Top:
		MoveWindow(pages.at(currectPage)->WindowHandle(), 0, 0, pageRect.width, pageRect.height, true);
		break;
	case ScrollEventArgs::ScrollType::EndScroll:
		break;
	case ScrollEventArgs::ScrollType::LineDown:
		MoveWindow(pages.at(currectPage)->WindowHandle(), pageRect.width - (rect.width >> 4), pageRect.height - (rect.height >> 4), pageRect.width, pageRect.height, true);
		break;
	case ScrollEventArgs::ScrollType::LineUp:
		MoveWindow(pages.at(currectPage)->WindowHandle(), pageRect.width + (rect.width >> 4), pageRect.height + (rect.height >> 4), pageRect.width, pageRect.height, true);
		break;
	case ScrollEventArgs::ScrollType::PageUp:
		break;
	}
}
void NAMESPACENAME::ScrollableControl::OnVerticalScroll(ScrollEventArgs& e)
{

}
void NAMESPACENAME::ScrollableControl::OnCreate()
{
}
